/**
 * 全局事件管理器
 */
export default class EventManager {

    private static events = {};

    /**
     * 添加一个全局事件监听，将通过EventManager.emit()触发
     * @param eventName 自定义的事件名称
     * @param callback 回调函数
     * @param thisObj 回调函数所在的类对象，如果用lambda写法，该参数可省略
     */
    static addEvent(eventName: string, callback: Function, thisObj?: any) {
        let handler = [callback, thisObj];
        let handlers: Array<any> = this.events[eventName];
        if (handlers == null) {
            handlers = [handler];
            this.events[eventName] = handlers;
        } else {
            let len = handlers.length;
            for (let i = 0; i < len; i++) {
                let handler = handlers[i];
                if (handler[0] == callback && handler[1] == thisObj) {
                    return;
                }
            }
            handlers.push(handler);
        }
    }

    /**
     * 移除一个已添加的全局事件监听
     * @param eventName 自定义的事件名称
     * @param callback 回调函数,若省略该参数将移除所有同名事件
     * @param thisObj 回调函数所在的类对象，是否省略应与addEvent时所传的参数一致
     */
    static removeEvent(eventName: string, callback?: Function, thisObj?: any) {
        let handlers: Array<any> = this.events[eventName];
        if (handlers != null) {
            let len = handlers.length;
            if (callback) {
                for (let i = 0; i < len; i++) {
                    let handler = handlers[i];
                    if (handler) {
                        if (thisObj && handler.length == 2) {
                            if (handler[0] == callback && handler[1] == thisObj) {
                                handlers.splice(i, 1);
                            }
                        } else if(handler.length == 1){
                            if (handler[0] == callback) {
                                handlers.splice(i, 1);
                            }
                        }
                    }
                }
                if (handlers.length == 0) {
                    this.events[eventName] = null;
                    delete this.events[eventName];
                }
            } else {
                this.events[eventName] = null;
                delete this.events[eventName];
            }
        }
    }

    /**
     * 触发一个全局事件
     * @param eventName 
     * @param params 
     */
    static emit(eventName: string, ...params: any[]) {
        let handlers: Array<any> = this.events[eventName];
        if (handlers != null) {
            for (var i = 0; i < handlers.length; i++) {
                let handler = handlers[i];
                let callback = handler[0];
                let thisObj = handler[1];
                callback.apply(thisObj, params);
            }
        }
    }

}
